home *** CD-ROM | disk | FTP | other *** search
Wrap
//============================================================================== // Scn18p9: AI Scenario Script for scenario 18 player 9 //============================================================================== /* AI owner: Dave Leary Scenario owner: Joe "The Golem" Gillum This AI does some basic training and then transports small groups to attack the player (4 axemen, 4 spearmen, and 1 scarab). Pacing of the attacks is controlled by the scenario designer. */ //============================================================================== // Need scn lib for some stuff here. include "scn lib.xs"; // Functions to check to see what's hanging around the point. int checkForMilitary(vector point = vector(-1,-1,-1)) { return(getUnassignedUnitCount(point, 30.0, cMyID, cUnitTypeLogicalTypeLandMilitary)); } //============================================================================== // Set Town Location //============================================================================== void setTownLocation(void) { //Look for the "Town Location" marker. kbSetTownLocation(kbGetBlockPosition("9954")); } //============================================================================== // miscStartup //============================================================================== void miscStartup(void) { // Difficulty Level check. int difflevel=-1; difflevel=aiGetWorldDifficulty(); //Startup message(s). aiEcho(""); aiEcho(""); aiEcho("Scn18P9 AI Start, filename='"+cFilename+"'."); aiEcho("Difficulty Level="+difflevel+"."); //Spit out the map size. aiEcho(" Map size is ("+kbGetMapXSize()+", "+kbGetMapZSize()+")."); //Cheat like a bastard. Once only, though. kbLookAtAllUnitsOnMap(); //Calculate some areas. kbAreaCalculate(1200.0); //Set our town location. setTownLocation(); //Reset random seed aiRandSetSeed(); //Allocate all resources to the root escrow. kbEscrowAllocateCurrentResources(); // Large AI attack response distance for this player aiSetAttackResponseDistance(50.0); } //============================================================================== //============================================================================== // Attack stuff. //============================================================================== //============================================================================== //Shared variables. int attackerUnitTypeIDSoldier1=cUnitTypeAxeman; int attackerUnitTypeIDSoldier2=cUnitTypeSpearman; int attackerUnitTypeIDMyth=cUnitTypeScarab; int attackerUnitTypeIDTransport=cUnitTypePirateShip; int attackPlan1ID=-1; //========================================================================================= // Kidd's cool configQuery function: used to create attack routes, etc. Oooh, lovin' that! //========================================================================================= /* bool configQuery( int queryID = -1, int unitType = -1, int action = -1, int state = -1, int player = -1, vector center = vector(-1,-1,-1), bool sort = false, float radius = -1 ) { if ( queryID == -1) { return(false); } if (player != -1) kbUnitQuerySetPlayerID(queryID, player); if (unitType != -1) kbUnitQuerySetUnitType(queryID, unitType); if (action != -1) kbUnitQuerySetActionType(queryID, action); if (state != -1) kbUnitQuerySetState(queryID, state); if (center != vector(-1,-1,-1)) { kbUnitQuerySetPosition(queryID, center); if (sort == true) kbUnitQuerySetAscendingSort(queryID, true); if (radius != -1) kbUnitQuerySetMaximumDistance(queryID, radius); } return(true); } */ //===================================================================================== // Attack Launcher. This is called from the scenario with an AI Func effect //===================================================================================== void attackLauncher(int whichAttack = -1) { int transportPlanID=aiPlanCreate("Transport Group", cPlanTransport); // "whichTransport" adds a specific transport to the plans. Victory conditions, chats, etc. // are tied to the concept of the main transport getting whacked. int whichTransport=-1; // Difficulty Level check. int difflevel=-1; difflevel=aiGetWorldDifficulty(); vector gatherPoint=kbGetBlockPosition("9952"); vector targetPoint=kbGetBlockPosition("9953"); if (transportPlanID >= 0) { aiEcho("*** ATTACK LAUNCHER SENDING TRANSPORT ***"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeAxeman, 0, 4, 4); aiPlanAddUnitType(transportPlanID, cUnitTypeSpearman, 0, 4, 4); aiPlanAddUnitType(transportPlanID, cUnitTypeScarab, 0, 1, 1); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); /* // Different composition depending on which attack. switch(whichAttack) { case 0: { aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeAxeman, 0, 4, 4); aiPlanAddUnitType(transportPlanID, cUnitTypeSpearman, 0, 4, 4); aiPlanAddUnitType(transportPlanID, cUnitTypeScarab, 0, 1, 1); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); break; } case 1: { whichTransport = kbGetBlockID("2637"); gatherPoint=kbGetBlockPosition("2640"); targetPoint=kbGetBlockPosition("2643"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeAxeman, 5, 5, 5); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportID, 0, whichTransport); break; } case 2: { whichTransport = kbGetBlockID("2633"); gatherPoint=kbGetBlockPosition("2658"); targetPoint=kbGetBlockPosition("2641"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeAxeman, 6, 6, 6); if ( difflevel > 0 ) { aiPlanAddUnitType(transportPlanID, cUnitTypeSlinger, 2, 2, 2); } aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportID, 0, whichTransport); break; } case 3: { whichTransport = kbGetBlockID("2788"); gatherPoint=kbGetBlockPosition("2640"); targetPoint=kbGetBlockPosition("2641"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeSlinger, 6, 6, 6); if ( difflevel > 0 ) { aiPlanAddUnitType(transportPlanID, cUnitTypeAnubite, 2, 2, 2); } aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportID, 0, whichTransport); break; } case 4: { whichTransport = kbGetBlockID("2634"); gatherPoint=kbGetBlockPosition("2639"); targetPoint=kbGetBlockPosition("2785"); aiPlanAddUnitType(transportPlanID, cUnitTypePirateShip, 1, 1, 1); aiPlanAddUnitType(transportPlanID, cUnitTypeAxeman, 7, 7, 7); aiPlanAddUnitType(transportPlanID, cUnitTypeScorpionMan, 1, 1, 1); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportTypeID, 0, cUnitTypePirateShip); aiPlanSetVariableInt(transportPlanID, cTransportPlanTransportID, 0, whichTransport); break; } } */ aiPlanSetVariableBool(transportPlanID, cTransportPlanMaximizeXportMovement, 0, true); aiPlanSetVariableVector(transportPlanID, cTransportPlanGatherPoint, 0, gatherPoint); aiPlanSetVariableVector(transportPlanID, cTransportPlanTargetPoint, 0, targetPoint); aiPlanSetDesiredPriority(transportPlanID, 75); // Don't return when finished. aiPlanSetVariableBool(transportPlanID, cTransportPlanReturnWhenDone, 0, false); aiPlanAddUnit(transportPlanID, whichTransport); aiPlanSetActive(transportPlanID); } } //============================================================================== // initAttack: Creates attack routes, etc. //============================================================================== /* void initAttack(int playerID=-1) { //Destroy all previous attacks (if this isn't the player we're already attacking. if (playerID != attackPlayerID) { //Reset the attack player ID. attackPlayerID=-1; //Destroy any previous attack plan. aiPlanDestroy(attackPlan1ID); attackPlan1ID=-1; aiPlanDestroy(attackPlan2ID); attackPlan2ID=-1; //Destroy our previous attack paths. kbPathDestroy(attackPath1ID); attackPath1ID=-1; kbPathDestroy(attackPath2ID); attackPath2ID=-1; //Destroy our previous attack routes. attackRoute1ID=-1; attackRoute2ID=-1; //Reset the number of attacks. numberAttacks=0; } //Save the player to attack. attackPlayerID=playerID; vector gatherPoint=kbGetBlockPosition("3989"); //Setup attack path 1 - go left attackPath1ID=kbPathCreate("Attack Path 1"); kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3990")); kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3991")); kbPathAddWaypoint(attackPath1ID, kbGetBlockPosition("3992")); //Create attack route 1. attackRoute1ID=kbCreateAttackRouteWithPath("Attack Route 1", gatherPoint, kbGetBlockPosition("3995")); if (attackRoute1ID >= 0) kbAttackRouteAddPath(attackRoute1ID, attackPath1ID); //Setup attack path 2 - go right attackPath2ID=kbPathCreate("Attack Path 2"); kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3990")); kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3991")); kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3993")); kbPathAddWaypoint(attackPath2ID, kbGetBlockPosition("3994")); //Create attack route 2. attackRoute2ID=kbCreateAttackRouteWithPath("Attack Route 2", gatherPoint, kbGetBlockPosition("3995")); if (attackRoute2ID >= 0) kbAttackRouteAddPath(attackRoute2ID, attackPath2ID); } */ //============================================================================== // setupAttack //============================================================================== /* bool setupAttack(int playerID=-1) { int randomPath=aiRandInt(2); //Info. aiEcho("Attacking Player "+playerID+"."); //If the player to attack doesn't match, init the attack. if (attackPlayerID != playerID) { initAttack(playerID); if (attackPlayerID < 0) return(false); } //Create an attack plan. int newAttackPlanID=aiPlanCreate("Attack Player"+attackPlayerID+" Attempt"+numberAttacks, cPlanAttack); if (newAttackPlanID < 0) return(false); //Target player (required). This must work. if (aiPlanSetVariableInt(newAttackPlanID, cAttackPlanPlayerID, 0, attackPlayerID) == false) return(false); //Gather point. vector gatherPoint=kbGetBlockPosition("3989"); //Set the target type. This must work. if (aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true) == false) return(false); //Unit types to attack. aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeUnit); aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeBuilding); //Attack route. if (randomPath == 0) { aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute1ID); } else { aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRouteID, 0, attackRoute2ID); } //Set the gather point and gather point distance. aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, gatherPoint); aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 10.0); //Set up the attack route usage pattern. aiPlanSetVariableInt(newAttackPlanID, cAttackPlanAttackRoutePattern, 0, cAttackPlanAttackRoutePatternRandom); //Add the unit types to the plan. aiPlanAddUnitType(newAttackPlanID, attackerUnitTypeID1, attackMinimumGroupSize, attackMaximumGroupSize, attackMaximumGroupSize); //Set the initial position. aiPlanSetInitialPosition(newAttackPlanID, gatherPoint); //Plan requires all need units to work (can be false). aiPlanSetRequiresAllNeedUnits(newAttackPlanID, true); //Activate the plan. aiPlanSetActive(newAttackPlanID); //Now, save the attack plan ID appropriately. aiPlanSetOrphan(attackPlan1ID, true); attackPlan1ID=newAttackPlanID; //Increment our overall number of attacks. numberAttacks++; } */ //============================================================================== // Attack Generator 1 - Axemen and friends //============================================================================== /* rule attackGenerator1 minInterval 75 inactive group AttackRules runImmediately { //See how many "idle" attack plans we have. Don't create any more if we have //idle plans. int numberIdleAttackPlans=aiGetNumberIdlePlans(cPlanAttack); if (numberIdleAttackPlans > 0) return; //If we have enough unassigned military units, create a new attack plan. int numberAvailableUnits=aiNumberUnassignedUnits(attackerUnitTypeID1); aiEcho("There are "+numberAvailableUnits+" axemen available for a new attack."); if (numberAvailableUnits >= attackMinimumGroupSize) setupAttack(1); } */ //============================================================================== // Attack enablers - enable attacks after initial timers expire //============================================================================== /* // Axemen rule attack1Enabler minInterval 240 active group AttackRules { xsEnableRule("attackGenerator1"); xsDisableSelf(); } */ //============================================================================== // Tech Researching Rules - medium axemen, medium slingers, medium spearmen //============================================================================== /* rule researchMediumAxemen minInterval 600 active { int planID=aiPlanCreate("Medium Axemen research at ten minutes.", cPlanResearch); if (planID < 0) return; aiPlanSetVariableInt(planID, cResearchPlanTechID, 0, cTechMediumAxemen); aiPlanSetVariableInt(planID, cResearchPlanBuildingTypeID, 0, cUnitTypeBarracks); aiPlanSetActive(planID); //Done. xsDisableSelf(); } */ //============================================================================== // Favor cheat //============================================================================== rule favorCheat minInterval 60 active group AttackRules { // Cheat for favor - 50 every minute aiResourceCheat( 9, cResourceFavor, 50.0 ); } //============================================================================== // Check the landing spot for unassigned dudes. //============================================================================== rule pollForMilitary minInterval 20 active { vector landingBeach=kbGetBlockPosition("9953"); int attackPlanSize = -1; attackPlanSize = checkForMilitary(landingBeach); if (attackPlanSize > 0) { aiEcho("P9 Attack Plan: Found "+attackPlanSize+" units on the beach."); int newAttackPlanID=aiPlanCreate("Beach Attack", cPlanAttack); if (newAttackPlanID >= 0) { //Target player. aiPlanSetVariableInt(newAttackPlanID, cAttackPlanPlayerID, 0, 1); aiPlanSetVariableVector(newAttackPlanID, cAttackPlanGatherPoint, 0, landingBeach); aiPlanSetVariableFloat(newAttackPlanID, cAttackPlanGatherDistance, 0, 40.0); //Add the unit(s). aiPlanAddUnitType(newAttackPlanID, cUnitTypeAxeman, 0, 4, 4); aiPlanAddUnitType(newAttackPlanID, cUnitTypeSpearman, 0, 4, 4); aiPlanAddUnitType(newAttackPlanID, cUnitTypeScarab, 0, 1, 1); aiPlanSetNumberVariableValues(newAttackPlanID, cAttackPlanTargetTypeID, 2, true); //Unit types to attack. aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 0, cUnitTypeBuilding); aiPlanSetVariableInt(newAttackPlanID, cAttackPlanTargetTypeID, 1, cUnitTypeUnit); aiPlanSetInitialPosition(newAttackPlanID, landingBeach); //Setup the vars. aiPlanSetDesiredPriority(newAttackPlanID, 40); aiPlanSetActive(newAttackPlanID); //Save this off and orphan the previous attack. aiPlanSetOrphan(attackPlan1ID, true); attackPlan1ID=newAttackPlanID; } } } //============================================================================== // MAIN. //============================================================================== void main(void) { //Startup. miscStartup(); //Gather points vector gatherPointAxemen=kbGetBlockPosition("9956"); vector gatherPointSpearmen=kbGetBlockPosition("9955"); vector gatherPointScarab=kbGetBlockPosition("9954"); //Create a simple plan to maintain 4 axemen. int maintainPlan1ID=aiPlanCreate("Maintain 4 "+kbGetProtoUnitName(attackerUnitTypeIDSoldier1), cPlanTrain); if (maintainPlan1ID >= 0) { //Must set the type of unit to train. aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanUnitType, 0, attackerUnitTypeIDSoldier1); //You can limit the number of units that are ever trained by this plan with this call. //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25); //Set the number of units to maintain in the world at one time. aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanNumberToMaintain, 0, 4); //Train units quickly, to ensure we have enough. aiPlanSetVariableInt(maintainPlan1ID, cTrainPlanFrequency, 0, 10); //Turn off training from multiple buildings. //aiPlanSetVariableBool(maintainPlanID, cTrainPlanUseMultipleBuildings, 0, false); //Set a gather target ID. //aiPlanSetVariableInt(maintainPlanID, cTrainPlanGatherTargetID, 0, 1234); //Set a gather point. aiPlanSetVariableVector(maintainPlan1ID, cTrainPlanGatherPoint, 0, gatherPointAxemen); //Activate the plan. aiPlanSetActive(maintainPlan1ID); } //Create a simple plan to maintain 4 spearmen. int maintainPlan2ID=aiPlanCreate("Maintain 4 "+kbGetProtoUnitName(attackerUnitTypeIDSoldier2), cPlanTrain); if (maintainPlan2ID >= 0) { //Must set the type of unit to train. aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanUnitType, 0, attackerUnitTypeIDSoldier2); //You can limit the number of units that are ever trained by this plan with this call. //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25); //Set the number of units to maintain in the world at one time. aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanNumberToMaintain, 0, 4); //Train units quickly, to ensure we have enough. aiPlanSetVariableInt(maintainPlan2ID, cTrainPlanFrequency, 0, 10); //Turn off training from multiple buildings. //aiPlanSetVariableBool(maintainPlanID, cTrainPlanUseMultipleBuildings, 0, false); //Set a gather target ID. //aiPlanSetVariableInt(maintainPlanID, cTrainPlanGatherTargetID, 0, 1234); //Set a gather point. aiPlanSetVariableVector(maintainPlan2ID, cTrainPlanGatherPoint, 0, gatherPointSpearmen); //Activate the plan. aiPlanSetActive(maintainPlan2ID); } //Create a simple plan to maintain 1 scarab. int maintainPlan3ID=aiPlanCreate("Maintain 1 "+kbGetProtoUnitName(attackerUnitTypeIDMyth), cPlanTrain); if (maintainPlan3ID >= 0) { //Must set the type of unit to train. aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanUnitType, 0, attackerUnitTypeIDMyth); //You can limit the number of units that are ever trained by this plan with this call. //aiPlanSetVariableInt(maintainPlanID, cTrainPlanNumberToTrain, 0, 25); //Set the number of units to maintain in the world at one time. aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanNumberToMaintain, 0, 1); //Train units quickly, to ensure we have enough. aiPlanSetVariableInt(maintainPlan3ID, cTrainPlanFrequency, 0, 10); //Turn off training from multiple buildings. //aiPlanSetVariableBool(maintainPlanID, cTrainPlanUseMultipleBuildings, 0, false); //Set a gather target ID. //aiPlanSetVariableInt(maintainPlanID, cTrainPlanGatherTargetID, 0, 1234); //Set a gather point. aiPlanSetVariableVector(maintainPlan3ID, cTrainPlanGatherPoint, 0, gatherPointScarab); //Activate the plan. aiPlanSetActive(maintainPlan3ID); } }